﻿using System;
using System.Diagnostics;

namespace AsyncEvtEcho
{
    abstract class RecvStateBase
    {
        // *************************************************************** //
        #region [ member fields ]

        protected volatile int m_readed;
        protected byte[] m_buffer;
        protected HeadBodyRecver m_context;

        #endregion

        // *************************************************************** //
        #region [ constructor ]

        protected RecvStateBase(HeadBodyRecver context)
        {
            m_context = context;
            m_readed = 0;
        }

        #endregion

        // *************************************************************** //
        #region [ public APIs ]

        public Tuple<byte[], int, int> NextRead
        {
            get { return Tuple.Create(m_buffer, m_readed, this.WholeLength - m_readed); }
        }

        public bool Receive(byte[] buffer, int offset, int count)
        {
            Debug.Assert(m_buffer == buffer && offset == m_readed);

            m_readed += count;
            int wholeLength = this.WholeLength;

            if (m_readed < wholeLength)
            {
                return false;
            }
            else
            {
                Debug.Assert(m_readed == wholeLength);

                m_readed = 0;
                return End();
            }
        }

        #endregion

        // *************************************************************** //
        #region [ helpers ]

        protected abstract bool End();
        public abstract int WholeLength { get; set; }

        #endregion
    }
}
